using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ExtensionLoader.Config;
using WorldServer.Extensions;

using OpenSimDbLinq;
using OpenSim.Framework;
using OpenMetaverse;

namespace WorldServer
{
    public class UserManager
    {
        private OpenSimDatabase userDatabase;

        public UserManager(IConfig databaseConfig)
        {
            LoadConfiguration(databaseConfig);
        }

        protected bool LoadConfiguration(IConfig userdbConfig)
        {
            #region ConnectToDatabase

            try
            {
                userDatabase = OpenSimUtils.LoadDatabaseFromConfig(userdbConfig);
                try
                {
                    var creationDateQuery = from user in userDatabase.Users select user;
                    var result = creationDateQuery.SingleOrDefault();

                    if (result != null)
                        Logger.Info("[UserManager] Connected to user database");
                    else
                        Logger.Warn("[OpenSimLogin] Connected to an empty user database");
                }
                catch (Exception ex)
                {
                    Logger.Error("[UserManager] Failed to establish a database connection: " + ex.Message);
                    return false;
                }


            }
            catch (Exception)
            {
                Logger.Error("[UserManager] Failed to load [OpenSimDatabase] or [OpenSimLogin] section from " + WorldServer.CONFIG_FILE);
                return false;
            }
            return true;

            #endregion ConnectToDatabase
        }

        public bool CreateUser()
        {
            Users user = new Users();
            string firstName = "", lastName = "", password = "", email = "";
            bool ok = false;

            while (!ok)
            {
                Console.Write("    First name [Default]: ");
                firstName = Console.ReadLine();
                if (firstName.Contains(" "))
                {
                    ok = false;
                    Console.WriteLine("    -> Cant have spaces in first name, try again");
                }
                else if (firstName == "")
                {
                    firstName = "Default";
                    ok = true;
                }
                else
                    ok = true;
            }

            ok = false;
            while (!ok)
            {
                Console.Write("    Last name [User]: ");
                lastName = Console.ReadLine();
                if (lastName.Contains(" "))
                {
                    Console.WriteLine("    -> Cant have spaces in last name, try again"); 
                    ok = false;
                }
                else if (lastName == "")
                {
                    lastName = "User";
                    ok = true;
                }
                else
                    ok = true;
            }

            ok = false;
            while (!ok)
            {
                Console.Write("    Password: ");
                password = Console.ReadLine();
                if (password == "")
                {
                    Console.WriteLine("    -> Password cannot be empty");
                    ok = false;
                }
                else
                    ok = true;
            }

            ok = false;
            while (!ok)
            {
                Console.Write("    Email []: ");
                email = Console.ReadLine();
                if (email.Contains(" "))
                {
                    Console.WriteLine("    -> Cant have spaces in password, try again");
                    ok = false;
                }
                else if (email == "")
                {
                    ok = true;
                }
                else if (!email.Contains("@"))
                {
                    Console.WriteLine("    -> Email must have @ character, try again");
                    ok = false;
                }
                else
                    ok = true;
            }

            string md5PasswdHash = Util.Md5Hash(Util.Md5Hash(password) + ":" + String.Empty);

            user.UUID = UUID.Random().ToString();
            user.UserName = firstName;
            user.LastName = lastName;
            user.Email = email;
            user.PasswordHash = md5PasswdHash;
            user.PasswordSalt = String.Empty;
            user.Created = Util.UnixTimeSinceEpoch();
            user.HomeLocationX = (float)128;
            user.HomeLocationY = (float)128;
            user.HomeLocationZ = (float)100;
            user.HomeLookAtX = (float)100;
            user.HomeLookAtY = (float)100;
            user.HomeLookAtZ = (float)100;
            user.HomeRegionID = UUID.Zero.ToString();
            user.CustomType = String.Empty;
            user.Partner = String.Empty;

            try
            {
                List<Users> bulkUsers = new List<Users>();
                bulkUsers.Add(user);
                userDatabase.Users.BulkInsert(bulkUsers);
                Logger.InfoFormat("[UserManager] Created new user {0} {1} to database", firstName, lastName);
                return true;
            }
            catch (Exception ex)
            {
                Logger.InfoFormat("[UserManager] Could not create new user {0} {1} to database", firstName, lastName);
                return false;
            }
        }
    }
}
